package core

import (
	"context"
	"strconv"
	"time"

	"suitbim.com/media/utils"
)

// Pusher管理端的主结构体，职责：
// 1. 维护与Dispatcher（remote media center）之间的信号来往（websocket协议）
// 2. 维护负责给Dispatcher推流（tcp）的client列表
type Manager struct {
	channels []*Channel
	Signer   *Signer
	ctx      context.Context
	cancel   context.CancelFunc
}

// NewManager 创建Manager实例
func NewManager() *Manager {
	ctx, cancel := context.WithCancel(context.Background())
	manager := Manager{ctx: ctx, cancel: cancel}
	manager.Signer = NewSigner(&manager)
	return &manager
}

// Start Manager开始工作
func (m *Manager) Start() {
	m.channels = Load_channels()
	m.ctx, m.cancel = context.WithCancel(context.Background())
	m.Signer.listen()
}

// OnMessage 收到来自Dispatcher的消息时
func (m *Manager) OnMessage(msg Message) {
	G.Log.Debugf("From Server, %s\n", utils.Struct2JsonString(&msg))
	mc := m.find(msg.Chan) //先去客户端寻找当前通道号是否存在
	if mc == nil {
		G.Log.Debugf("Channel [%s] can not be matched.", msg.Chan)
		if msg.Sign == SIG_PTZ_START {
			m.Signer.SendSignal(&Message{Sign: SIG_PTZ_END, Chan: msg.Chan, Content: SIG_PTZ_NOT_FOUND})
		}
		return
	}

	switch msg.Sign {
	case SIG_OPEN:
		// 先判断当前通道是否已经初始化完毕，没有初始化则先初始化
		if !mc.Ready {
			mc.Init(msg)
		}
		// 开启当前通道的推流操作
		mc.Start()
	case SIG_CLOS:
		// 关闭当前通道的推流操作
		mc.Stop()
	//TODO: PTZ
	// case SIG_ACTS:
	// 	m.dealPooledViewers(msg)
	case SIG_CAPTURE:
		// 开始截图
		code, err := strconv.Atoi(mc.config.ChannelCode[2:])
		if err != nil {
			G.Log.Error("Signal ", msg.Sign, " trans err")
			return
		}
		capture := NewCapture(code, mc.config.MediaPath)
		capture.Start()
	case SIG_PTZ_START:
		// 云台操作
		address := mc.config.Address
		username := mc.config.Username
		password := mc.config.Password
		if address == "" || username == "" || password == "" {
			G.Log.Errorf("Curr channel %s not support ptz", mc.config.ChannelCode)
			m.Signer.SendSignal(&Message{Sign: SIG_PTZ_END, Chan: mc.config.ChannelCode, Content: SIG_PTZ_NOT_FOUND})
			return
		}

		ptzService := NewPTZ(mc.config.ChNo)
		recorderMap := map[string]any{
			"address":  address,
			"username": username,
			"password": password,
		}
		ptzService.SetData(recorderMap)
		err = ptzService.RunDirector(msg.Content)
		var content = SIG_PTZ_SUCCESS
		if err != nil {
			// 发送失败的状态
			content = SIG_PTZ_FAIL
		}
		m.Signer.SendSignal(&Message{Sign: SIG_PTZ_END, Chan: mc.config.ChannelCode, Content: content})
	default:
		G.Log.Error("Signal ", msg.Sign, " is didn't pitch!")
	}
}

// OnSignerDisconnected 当与Dispatcher失去信号连接时
func (m *Manager) OnSignerDisconnected() {
	// 停止所有正在推流的通道
	for _, c := range m.channels {
		c.Stop()
	}
	m.cancel()
	// 重新发起连接
	RetryDuration := (time.Duration)(G.Dispatcher.Signal.RetryDuration)
	time.Sleep(time.Second * RetryDuration)
	m.Start()

}

// 处理Dispatcher发来的信号：当前激活中的通道列表
func (m *Manager) dealPooledViewers(Message) {

}

func (m *Manager) find(channelCode string) *Channel {
	for _, cp := range m.channels {
		if cp.config.ChannelCode == channelCode {
			return cp
		}
	}
	return nil
}
